package com.yeziji.security.common;

import cn.hutool.core.util.StrUtil;
import com.yeziji.security.utils.JwtUtils;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import java.io.Serializable;

/**
 * 生成加密令牌
 *
 * @author hwy
 * @since 2023/11/12 14:43
 **/
@Data
@Builder
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class SecurityToken implements Serializable {
    private static final long serialVersionUID = -3210273922869566933L;

    /**
     * 初始令牌
     */
    private String originalToken;

    /**
     * 刷新令牌
     */
    private String refreshToken;

    /**
     * 是否发生了改变
     */
    private boolean change;

    /**
     * 是否遗弃
     */
    private boolean deprecated;

    /**
     * 判断原来的 token 是否已经过期
     *
     * @return {@link Boolean} 是否已过期
     */
    public boolean expired() {
        return StrUtil.isBlank(this.originalToken) ||
                (StrUtil.isNotBlank(this.originalToken) && JwtUtils.isExpired(this.originalToken));
    }

    /**
     * 判断刷新的 token 是否已经过期
     *
     * @return {@link Boolean} 是否已过期
     */
    public boolean refreshExpired() {
        return StrUtil.isBlank(this.refreshToken) ||
                (StrUtil.isNotBlank(this.refreshToken) && JwtUtils.isExpired(this.refreshToken));
    }


    /**
     * 判断 token 对象是否完全过期
     *
     * <p>如果原来的 token 已经过期了, 如果没有刷新 token 那么就视为过期; 如果有刷新 token 那么还需要判断刷新 token 是否已经过期</p>
     *
     * @return {@link Boolean} 是否已完全过期
     */
    public boolean completelyExpired() {
        return this.expired() && this.refreshExpired();
    }

    /**
     * 判断 token 是否相同
     *
     * @param token token 令牌
     * @return {@link Boolean} token 是否相同
     */
    public boolean tokenEquals(String token) {
        if (StrUtil.isBlank(token)) {
            return false;
        }

        return this.originalToken.equals(token);
    }

    /**
     * 赋值拷贝一个新的对象值
     *
     * @param securityToken 拷贝对象
     */
    public void copy(SecurityToken securityToken) {
        this.setOriginalToken(securityToken.getOriginalToken());
        this.setRefreshToken(securityToken.getRefreshToken());
    }
}
